<Html>
  <head>
    <title>运行原理</title>
  </head>
  <body>
    <script>
      // 性能优化专题

           /*
              一、运行原理

                      1、"逻辑层" 和 "视图层" 分离，且非 H5端通信有折损

                                  uni-app 在非 H5端运行时，从架构上分为 "逻辑层" 和 "视图层"两个部分。逻辑层负责执行业务逻辑，也就是运行js代码，视图层负责页面渲染。

                                  虽然开发者在一个vue页面里写 js 和 css ,但其实，编译时就已经将它们拆分了。


                      2、逻辑层详解

                                  逻辑层是运行在一个独立的 jscore里的，它不依赖于本机的 webview ，所以一方面它没有浏览器兼容的未提，

                              可以在Android4.4 上跑 es6代码，另一方面，它无法运行 window、document、navigator、localstorage等浏览器专用的js API.

                                  jscore 就是一个标准的js引擎，标准js是可以正常运行的，比如 if、for、各种字符串、日期处理等。

                                  js 和 浏览器的区别要注意区分开来。

                                  ①、所谓浏览器的js引擎，就是 jscore 或 v8 的基础上新增了一批浏览器专用API，比如 dom;

                                  ②、node.js 引擎，则是v8 基础上补充一些PC专用API，比如本地 i0；

                                  ③、那么 uni-app 的App端 和 小程序端的js引擎，其实是在 jscore 上补充了一批手机端常用的 JS API ，比如扫码。


                                  这些不同的js引擎的关系如下图：

                                      https://img.cdn.aliyun.dcloud.net.cn/uni-app/jscore.jpg


                        3、视图层详解

                                H5 和 小程序平台，以及 app-vue ，视图层是webview。  而 app-nvue 的视图层是基于 weex改造的原生渲染视图。

                                关于 webview, 在ios 上，制衡呢使用iOS提供的 webview （默认是 WKWebview）。 它有一定的浏览器兼容问题，ios版本不同，它的表现有细微差别(一般可忽略不计)

                                Android 上小程序大多自带了一个几十M的 chromuin webview ，而 App端没办法带这么大体积的三方包，

                                所以App端默认使用了 Android system webview ，这个系统webview 跟随手机不同而有差异。

                                当然， App端也支持使用腾讯X5引擎，此时可以在Android端统一视图层。

                                所以 uni-app 的 js基本没有不同手机的兼容问题(因为js引擎自带了)，而视图层的css，在app-vue上使用系统webview时，

                                会有手机浏览器的css兼容问题。此时或者不要用太新的css语法，或者继承腾讯X5引擎。


                         4、逻辑层和视图层分离的利与弊

                                逻辑层和视图层分离，好处是 js 运算不卡渲染，最简单直接的感受就是： 窗体动画稳。

                                如果开发者使用过App ，应该由概念，webview 新窗体一边做进入动画，一边自身渲染，很容易卡动画。

                                而uni-app则无需写"预载代码"，新窗体渲染块且动画稳定。

                                但是两层分离也带来一个坏处，这两层互相通信，其实是由损耗的。

                                ios还好，但Android低端机上，每次通信都要耗时几十毫秒。平时看不出来，但有几个场景表现明显：

                                    ①、连续高帧率绘制 canvas 动画，会发现还不如 webview内部绘制流畅

                                    ②、视图层滚动、跟手操作，不停反馈给逻辑层，js 再处理逻辑并通知视图层做出对应更新。此时会发现交互不跟手或卡。

                                不管小程序还是 app ,不管 app-vue 还是 app-nvue ，都有这两个层通信损耗的问题。

                                解决这类问题，在 webview 渲染和原生渲染应用了不同的做法：

                                     ①、webview渲染的视图层：

                                          在 app-vue 和微信小程序上，提供了一种运行于视图层的专属 js ,微信叫做 "wxs".

                                          wxs中可以监听手势，以 uni ui 的 swiperAction 组件为例，手指拖动，侧边的列表惨淡要跟手滑出，此时

                                          就需要使用wxs才能实现流畅效果。还有插件市场里一些自定义下拉刷新的插件，通过 wxs实现了更高的性能体验。

                                          uni-app 支持把 wxs编译到微信小程序、App 和 H5中。

                                          微信里对wxs限制较多，只能实现有限的功能。 app端提供了更强大的 renderjs，并兼容到 h5平台。

                                          比如 canvas 动画，微信的 canvas 无法通过 wxs操作，js不同绘制canvas动画因通信折损而无法流畅。

                                          uni-app的 app-vue 里的 canvas 对象设计在 webview 视图层的，通过renderjs可以在视图层直接操作canvas动画，

                                          将不再有通信折损，实现更流畅的效果，详见 ： renderjs https://uniapp.dcloud.net.cn/tutorial/renderjs.html


                                     ②、原生渲染的视图层

                                          在 app-nvue里，逻辑层和视图层的折损一样存在。包括 reavt native 也有这个问题。所以也千万被意味原生渲染就多么高级。

                                          weex提供了一套 bindingx机制，可以在 js里一次性传递一个表达式给原生层，有原生层解析后根据指令操作原生的视图层，

                                          避免反复跨层通信。这个技术在 uni-app 里也可以使用。

                                          bindingx 作为一种表达式，它的功能更呢不及js强大，但手势监听、动画还是可以实现的，比如 Uni ui的 swiperActin组件在app-vue 下运行时会自动启用 bindingx，以实现流畅跟手。

                        5、app-vue 和 小程序的数据更新，分页面积和组件级

                                对于复杂页面，更新某个区域的数据时，需要把这个区域做成组件，这样更新数据时就只更新这个组件，
                                
                                否则会整个页面的数据更新，造成点击延迟卡顿。
                                
                                比如微博长列表页面，点击一个点赞图标，赞数要立即+1,此时这个点赞按钮一定要做成组件。否则这个+1会引发页面级所有数据的从js层项视图层的同步。

                                app-vue 和 h5 不存在此未提。造成差异的原因是小程序目前只提供了组件差量更新的机制，不能自动计算所有页面差量。

           */    

    </script>
  </body>
</Html>